﻿namespace System.ServiceModel.DomainServices.Client
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Linq;

    public sealed class EntityConflict
    {
        private Entity _currentEntity;
        private bool _isDeleted;
        private Entity _originalEntity;
        private ReadOnlyCollection<string> _propertyNames;
        private Entity _storeEntity;

        internal EntityConflict(Entity currentEntity, Entity storeEntity, IEnumerable<string> propertyNames, bool isDeleted)
        {
            if (currentEntity == null)
            {
                throw new ArgumentNullException("currentEntity");
            }
            this._currentEntity = currentEntity;
            this._isDeleted = isDeleted;
            if (!isDeleted)
            {
                if (storeEntity == null)
                {
                    throw new ArgumentNullException("storeEntity");
                }
                if (propertyNames == null)
                {
                    throw new ArgumentNullException("propertyNames");
                }
                this._storeEntity = storeEntity;
                this._propertyNames = propertyNames.ToList<string>().AsReadOnly();
            }
        }

        public void Resolve()
        {
            if (this.CurrentEntity.EntityConflict != null)
            {
                if (this.IsDeleted)
                {
                    throw new InvalidOperationException(Resource.EntityConflict_CannotResolveDeleteConflict);
                }
                this.CurrentEntity.UpdateOriginalValues(this.StoreEntity);
                MetaMember versionMember = this._currentEntity.MetaType.VersionMember;
                if (versionMember != null)
                {
                    object obj2 = versionMember.GetValue(this._storeEntity);
                    Dictionary<string, object> entityStateToApply = new Dictionary<string, object>();
                    entityStateToApply.Add(versionMember.Member.Name, obj2);
                    this._currentEntity.ApplyState(entityStateToApply);
                }
                this.CurrentEntity.EntityConflict = null;
            }
        }

        public Entity CurrentEntity
        {
            get
            {
                return this._currentEntity;
            }
        }

        public bool IsDeleted
        {
            get
            {
                return this._isDeleted;
            }
        }

        public Entity OriginalEntity
        {
            get
            {
                if (this._originalEntity == null)
                {
                    IDictionary<string, object> originalValues = this._currentEntity.OriginalValues;
                    if (originalValues != null)
                    {
                        this._originalEntity = (Entity) Activator.CreateInstance(this.CurrentEntity.GetType());
                        this._originalEntity.ApplyState(originalValues);
                    }
                }
                return this._originalEntity;
            }
        }

        public IEnumerable<string> PropertyNames
        {
            get
            {
                if (this._isDeleted)
                {
                    throw new InvalidOperationException(Resource.EntityConflict_IsDeleteConflict);
                }
                return this._propertyNames;
            }
        }

        public Entity StoreEntity
        {
            get
            {
                return this._storeEntity;
            }
        }
    }
}

